#ifndef DW_GRAPHICS_MATERIAL_H
#	define DW_GRAPHICS_MATERIAL_H

#include "color.h"

namespace dw {
	namespace graphics {

using system::ISerializer;

class Pass;

class Material : public system::ISerializable
{

	typedef std::vector< Pass* >				PassArray;
	
	typedef PassArray::iterator PassIterator;

	typedef PassArray::const_iterator PassConstIterator;

// Constructors
public:

																	Material(const std::string& name = "");
	
																	Material(const Colorf& ambient, const Colorf& diffuse, const Colorf& specular);

	virtual													~Material();


// Methods
public:

	Material& operator=(const Material&);

	
	
	const std::string& getName() const { return _name; }

	const Colorf& getAmbient() const { return _ambient; }

	const Colorf& getDiffuse() const { return _diffuse; }
	
	const Colorf& getSpecular() const { return _specular; }
	
	const Colorf& getEmissive() const { return _emissive; }

	const float& getShininess() const { return _shininess; }
	
	const float getRoughness() const { return 1 / _shininess; }

	const float& getOpacity() const { return _opacity; }

	const float& ka() const { return _ka; }
	
	const float& kd() const { return _kd; }
	
	const float& ks() const { return _ks; }
	
	const float& kr() const { return _kr; }
	
	const float& kt() const { return _kt; }
	
	const float& ior() const { return _ior; }

	Colorf& getAmbient() { return _ambient; }
	
	Colorf& getDiffuse() { return _diffuse; }
	
	Colorf& getSpecular() { return _specular; }

	float& getShininess() { return _shininess; }

	float& ka() { return _ka; }
	
	float& kd() { return _kd; }
	
	float& ks() { return _ks; }
	
	float& kr() { return _kr; }
	
	float& kt() { return _kt; }
	
	float& ior() { return _ior; }

	Pass* getPass(const unsigned i) const	{ return _passes[i]; }


	
	void setName(const std::string& name)			{ _name = name; }
	
	void setAmbient(const Colorf& ambient)			{ _ambient = ambient; }
	
	void setDiffuse(const Colorf& diffuse)			{ _diffuse = diffuse; }
	
	void setSpecular(const Colorf& specular)		{ _specular = specular; }

	void setEmissive(const Colorf& emissive)		{ _emissive = emissive; }

	void setOpacity(const float& opacity)			{ _diffuse.a = opacity; _ambient.a = opacity; _specular.a = opacity; _opacity = opacity; }

	void setShininess(const float& shininess)	{ _shininess = shininess; }



	Pass* createPass();
	
	void removePass(const unsigned);
	
	void removePass(Pass*);

	void addPass(Pass*);



	bool isTransparent() const ;



	uint32 begin() const ;

	void end() const ;

	void beginPass(const unsigned i) const ;

	void endPass(const unsigned i) const ;



	std::string getSignature() const ;

	void serialize(ISerializer* serializer) const ;

	void deserialize(ISerializer* serializer);

// Fields
private:

	/// Name of the material.
	std::string _name;

	/// Passes used for rendering this material.
	PassArray _passes;
	
	Colorf _ambient, _diffuse, _specular, _emissive;
	
	float _ka, _kd, _ks, _kr, _kt, _ior;

	float _shininess;

	float _opacity;
	
private:

	friend 
	std::ostream& operator<<(std::ostream&, const Material&);
	
	friend
	std::istream& operator>>(std::istream&, Material&);

};

typedef Material Effect;

typedef Material* MaterialPtr;

	} // namespace graphics
} // namespace dw

#endif // !DW_GRAPHICS_MATERIAL_H
